package cn.jasonone.him.jmx;

import java.lang.management.ManagementFactory;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.rmi.registry.LocateRegistry;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;

import org.springframework.stereotype.Component;

import cn.hutool.json.JSONUtil;
import cn.jasonone.him.HimProperties;
import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class HimJMXServer {
	/**
	 * 密码文件在环境的KEY
	 */
	private static final String RMI_PASSWORD_FILE_ENVIRONMENT = "jmx.remote.x.password.file";
	/**
	 * 账号文件在环境的KEY
	 */
	private static final String RMI_ACCESS_FILE_ENVIRONMENT = "jmx.remote.x.access.file";
	/**
	 * 密码文件的文件名
	 */
	private static final String RMI_PASSWORD_FILE = "him.password";
	/**
	 * 账号文件的文件名
	 */
	private static final String RMI_ACCESS_FILE = "him.access";
	@Resource
	private HimProperties himProperties;
	@Resource
	private HimMBean himMBean;

	public void start() {
		HimJmxProperties jmxProperties = himProperties.getJmx();
		if (jmxProperties != null && jmxProperties.isEnable()) {
			try {
				MBeanServer server = ManagementFactory.getPlatformMBeanServer();
				ObjectName name = new ObjectName("himMBean:name=him");
				server.registerMBean(himMBean, name);
				log.debug("启动JMX监控");
				log.trace("启动JMX监控:{}", JSONUtil.toJsonStr(jmxProperties));
				if (jmxProperties.isRmiEnable()) {
					LocateRegistry.createRegistry(jmxProperties.getRmiPort());
					String rmiUrl = "service:jmx:rmi:///jndi/rmi://" + jmxProperties.getRmiHost() + ":"
							+ jmxProperties.getRmiPort() + "/himrmi";
					JMXServiceURL serviceURL = new JMXServiceURL(rmiUrl);
					Map<String, Object> environment = new HashMap<>();
					if (jmxProperties.isAuthorizationEnable()) {
						environment.put(RMI_ACCESS_FILE_ENVIRONMENT, RMI_ACCESS_FILE);
						environment.put(RMI_PASSWORD_FILE_ENVIRONMENT, RMI_PASSWORD_FILE);
						{
							//创建账号文件,并配置账号和权限
							Path access = Paths.get(RMI_ACCESS_FILE);
							Files.deleteIfExists(access);//删除旧的文件
							Files.createFile(access);//创建新的文件
							Files.write(access,(jmxProperties.getUserName()+" "+jmxProperties.getUserAuthorization()).getBytes());
							log.trace("RMI账号文件:{}",access.toAbsolutePath());
						}
						{
							//创建密码文件,并且配置账号密码
							Path password = Paths.get(RMI_PASSWORD_FILE);
							Files.deleteIfExists(password);//删除旧的文件
							Files.createFile(password);//创建新的文件
							Files.write(password,(jmxProperties.getUserName()+" "+jmxProperties.getPassword()).getBytes());
							log.trace("RMI密码文件:{}",password.toAbsolutePath());
						}
					
					}
					JMXConnectorServer connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(serviceURL,
							environment, server);
					connectorServer.start();
					log.debug("开启JMX RMI控制台访问:{} 用户名:{} 密码:{} 权限:{}", rmiUrl,jmxProperties.getUserName(),jmxProperties.getPassword(),jmxProperties.getUserAuthorization());
				}

			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}
